#!/usr/bin/env ruby
############################################################################
#    Copyright (C) 2009 by Davide Monfrecola                               #
#    davide.monfrecola@gmail.com                                           #
#                                                                          #
#    This program is free software; you can redistribute it and#or modify  #
#    it under the terms of the GNU General Public License as published by  #
#    the Free Software Foundation; either version 2 of the License, or     #
#    (at your option) any later version.                                   #
#                                                                          #
#    This program is distributed in the hope that it will be useful,       #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#    GNU General Public License for more details.                          #
#                                                                          #
#    You should have received a copy of the GNU General Public License     #
#    along with this program; if not, write to the                         #
#    Free Software Foundation, Inc.,                                       #
#    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             #
############################################################################

=begin
This class of object contains all the information about a web page
There's an instance of this class for every web page result
=end

class WebDocument
	attr_reader :content
														
	#@@table_size = 209503
	#@@table_size = 1200583 too big
	@@table_size = 122561
	@@count = 0
	@@expTable = []
	@@collision = 0
	@last_hashvalue = 0
	@last_fbvalue = 0
	@doc_name = ""
	@text = ""

	def initialize(url)
		@bsize = $bsize			# get the block size option
		i = 0
		j = @bsize - 1
		@doc_name = url
		@mutex = Mutex.new
		#@filename = filename
		@content = Array.new(0)	
		@mutex.lock
			@@count += 1								 # Array of elements [w, pos]
		@mutex.unlock
		# integers indexes list (M elements)
		# Each index points to the begin of the word block
		@indexTable = Array.new(@@table_size) {Array.new(0)}
		if @@expTable == []
			init_expTable
			#$logger.info("Document") {"@@expTable initialized"}
		end #if
		#$logger.info("Document") {"reading #{url}"}
		if ((@text = Readers::get_text(url)) == "")
			#puts "Empty file #{url} return nil"
			return nil
		end #if
		@content = parse(@text)
		#$logger.info("Document") {"#{url} read | @content.size:#{@content.size}"}
	end #init
	
	# return url used to create self 
	def doc_name()
		return @doc_name
	end #doc_name
	
	def to_s()
		return @text
	end #to_s
	
	# return the words number in the self parsing
	def num_words()
		return @content.size
	end #num_words


	# return list of k words.
	# n: position of the first word
	# k: number of words
	def get_words(n, k)
		wordlist = []
		for i in n...n+k
			begin
				wordlist << @content[i][0]+" "
			rescue NoMethodError								 # if the last block is small then 5 words 
				return wordlist
			end #rescue
		end
		return wordlist
	end #get_words

  # return the position in @text of the element in @content
  # It is used to find the char position in @text of the given @content index
  # @content = [[word, position],...] return the value of position of the given index 
  def get_char_position(content_index)
    begin
      @content[content_index][1]
    rescue StandardError
      return @content[content_index-1][1]
    end
  end

	# return the position in @text of the element in @content
  	# It is used to find the char position in @text of the given @content index
  	# @content = [[word, position],...] return the value of position of the given index
	def get_last_char_position(content_index)
      @content[content_index-1][1] + @content[content_index-1][0].size
  	end
  	
  private # private method
	
	def blockhash(a)
		hasharray = Array.new(0)
		sum = 0
		i = @bsize-1
		for x in a
			hasharray << (x.hash * @@expTable[i]) % @@table_size
			i = i-1
		end
		hasharray.each {|elem| sum = sum + elem}
		@last_hashvalue = sum % @@table_size
		@last_fbvalue = hasharray[0] 						# farlo solo se non master document
		return (sum % @@table_size) 						# return hash of block
	end #blockhash
	
=begin
Blockhash using the Bentley Ilroy algorithm
- a: word list
=end
	def blockhash_Bentley(a)
		hasharray = Array.new(0)
		temp = 0
		temp = ((@last_hashvalue - @last_fbvalue) * ($p.to_i))+(a[@bsize-1].hash)
		@last_hashvalue = temp % @@table_size
		@last_fbvalue = (((a[0].hash) * @@expTable[@bsize-1])) % @@table_size
		return (temp % @@table_size) 						# return hash of block
	end # blockhash_Bentley
	
	# convert accented vowels in place
	def remove_accent!(s)
		s.gsub!(/[àéèìòù]/) do |c|
			case c
				when  /à/: "a"
				when  /ì/: "i"
				when  /ò/: "o"
				when  /ù/: "u"
				else       "e"
			end
		end
		return s
	end

=begin
Parse s into a sequence of words returning the list of words 
together with their starting position in the input
=end
	def parse(s,wlimit=3)
		wlist = []
		word_def = /[[:alpha:]|àèéìòù]+/ # regex
		s.scan(word_def) do |w| 
			if w.size >= wlimit
				wpos = $`.size          			# starting position in s of w
				remove_accent!(w)      				# convert accented chars in place
				w.downcase!             			# convert case
				wlist << [w, wpos]      			# save in list
			end
		end
		wlist
	end
	
	# initialize the expTable
	def init_expTable
		for i in 0...@bsize
			@@expTable << ($p.to_i)**i
		end
	end #expTable

end # class WebDocument
